package com.woniuxy.zuul.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.woniuxy.commons.enums.ResultEnum;
import com.woniuxy.commons.util.ResponseResult;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author zhangyong
 * @Date 2021/8/4 0004
 */
@Component
public class limitFilter extends ZuulFilter {

    //创建限流器，指定令牌数量(google的)
    private static final RateLimiter RATELIMITER = RateLimiter.create(500);
    private static  int count = 0;

    //指定filter的类型
    @Override
    public String filterType() {
        //直接返回字符串
        return "pre";
    }

    //执行的顺序
    @Override
    public int filterOrder() {
        return -100;
    }

    //是否要过滤，如果返回的是true，才会去执行run()方法
    @Override
    public boolean shouldFilter() {
        //编写判断哪些需要登录、权限判断的业务逻辑
        //1.得到上下文
        RequestContext context = RequestContext.getCurrentContext();
        //2.得到request
        HttpServletRequest request = context.getRequest();
        //3.得到url
        String uri = request.getRequestURI();
        //
        //System.out.println(uri);
        //判断uri是否需要登录、鉴权，如果不需要返回false，如果需要run()返回true

        return true;
    }

    //编写处理锅炉的业务逻辑，判断是否登录，鉴权（判断是否有权限），限流等操作
    @Override
    public Object run() throws ZuulException {
        //System.out.println("filter执行过滤");
        RequestContext context = RequestContext.getCurrentContext();
        //判断能否拿到令牌
        if (RATELIMITER.tryAcquire()) {
            System.out.println(count++);
            //没拿到令牌，结束请求返回一个结果
            context.setSendZuulResponse(false); //false不继续处理请求，到此为止
            //设置返回结果
            ResponseResult<String> result = new ResponseResult<>();
            result.setCode(500);
            result.setStatus(ResultEnum.SYSTEM_BUSY);
            result.setMessage("服务器忙，请稍后再试");
            //使用返回结果
            HttpServletResponse response = context.getResponse();
            //设置响应头
            response.setContentType("application/json; charset=UTF-8");

            try {
                //转json
                String json = new ObjectMapper().writeValueAsString(result);
                //写数据
                response.getWriter().write(json);

            }catch (Exception e){
                e.printStackTrace();
            }

        }
        return null;
    }
}
